<?php
/**
 * "Post" Model
 *
 * @author hiscaler <hiscaler@gmail.com>
 * @link http://www.yuandot.com/
 * @copyright Copyright &copy; 2009-2010 Yuandot Information Technology CO.,LTD.
 * @license http://doit.yuandot.com/license/
 */

class Post extends CActiveRecord {
    /**
     * The followings are the available columns in table 'www_posts':
     * @var integer $id
     * @var string $title
     * @var string $body
     * @var integer $status
     * @var integer $clicks_count
     * @var integer $published_at
     * @var integer $order_pos
     * @var integer $updated
     * @var integer $created
     */

    public $clicks_count = 0;
    private $_oldTags;

    const PICTURE_POST_NO = 0;
    const PICTURE_POST_YES = 1;

    /**
     * Returns the static model of the specified AR class.
     * @return CActiveRecord the static model class
     */
    public static function model($className=__CLASS__) {
        return parent::model($className);
    }

    /**
     * @return string the associated database table name
     */
    public function tableName() {
        return '{{posts}}';
    }

    /**
     * @return array validation rules for model attributes.
     */
    public function rules() {
    // NOTE: you should only define rules for those attributes that
    // will receive user inputs.
        return array(
            array('title, author, source, body, published_at, node_id, user_id', 'required'),
            array('status, allow_comment, clicks_count, published_at, order_pos, updated, created, node_id, user_id', 'numerical', 'integerOnly' => true),
            array('is_picture_post, is_recommend, is_picking, allow_comment', 'boolean', 'falseValue' => 0, 'trueValue' => 1),
            array('title_color', 'length', 'max' => 7),
            array('title_style', 'length', 'max' => 200),
            array('author', 'length', 'max' => 60),
            array('title, source, keywords, picture_saved_path', 'length', 'max' => 200),
            array('tags', 'length', 'max' => 400),
//            array('tags', 'match', 'pattern'=>'/^[\w\s,]+$/', 'message' => 'Tags can only contain word characters.'),
//            array('tags', 'match', 'pattern'=>'/^[\x{4e00}-\x{9fa5},]+$/u', 'message' => 'Tags can only contain word characters.'),
            array('tags', 'match', 'pattern'=>'/^[\x00-\xff,]+$/', 'message' => 'Tags can only contain word characters.'),
            array('tags', 'normalizeTags'),
            array('picture_saved_path', 'file', 'on' => 'is_picture_post',
                'allowEmpty' => false,
                'types' => 'jpg, jpeg, gif',
                'maxSize' => 1024 * 1024 * 10,
            ),
        );
    }

    /**
     * @return array relational rules.
     */
    public function relations() {
        return array(
            // 所属节点
            'node' => array(self::BELONGS_TO, 'Node', 'node_id'),
            // 发布者
            'user' => array(self::BELONGS_TO, 'User', 'user_id'),
            // 评论列表
            'comments' =>  array(self::HAS_MANY, 'PostComment', 'post_id'),
            // 评论数量
            'commentCount' => array(self::STAT, 'PostComment', 'post_id',
                'condition' => 'status = ' . PostComment::STATUS_PENDING),
        );
    }

    /**
     * @return array customized attribute labels (name=>label)
     */
    public function attributeLabels() {
        return array(
            'id' => 'Id',
            'user_id' => Yii::t('post', 'user_id'),
            'node_id' => Yii::t('common', 'node_id'),
            'is_recommend' => Yii::t('common', 'is_recommend'),
            'is_picking' => Yii::t('common', 'is_picking'),
            'title' => Yii::t('post', 'title'),
            'title_color' => Yii::t('options', 'color'),
            'title_style' => Yii::t('options', 'style'),
            'author' => Yii::t('post', 'author'),
            'source' => Yii::t('post', 'source'),
            'keywords' => Yii::t('post', 'keywords'),
            'tags' => Yii::t('post', 'tags'),
            'allow_comment' => Yii::t('post', 'allow_comment'),
            'body' => Yii::t('post', 'body'),
            'status' => Yii::t('post', 'status'),
            'clicks_count' => Yii::t('common', 'clicks_count'),
            'published_at' => Yii::t('post', 'published_at'),
            'order_pos' => Yii::t('common', 'order_pos'),
            'is_picture_post' => Yii::t('post', 'is_picture_post'),
            'picture_saved_path' => Yii::t('post', 'picture_saved_path'),
            'updated' => Yii::t('common', 'updated'),
            'created' => Yii::t('common', 'created'),
        );
    }

    // "status" field Icon format
    public function getStatusIconFormat() {
        switch ($this->status) {
            case Options::STATUS_DRAFT:
                $img = 'status_draft.gif';
                break;
            case Options::STATUS_PUBLISHED:
                $img = 'status_published.gif';
                break;
            case Options::STATUS_PENDING_DELETE:
                $img = 'status_pending_delete.gif';
                break;
            default:
                $img = 'status_unknown.gif';
        }
        return CHtml::image(Yii::app()->assetManager->baseUrl . '/backend/images/' . $img);
    }

    // status AJax submit
    public function getStatusAjaxFormat() {
        return CHtml::ajaxLink($this->statusIconFormat,
            Yii::app()->createUrl('backend/posts/changeStatus'),
            array(
                'type' => 'POST',
                'data' => 'id=' . $this->id,
                'dataType' => 'text',
                'update' => "#yuandot{$this->id}",
            ),
            array('id' => "yuandot{$this->id}")
        );
    }

    // “是否推荐”图标格式
    public function getIsRecommendIconFormat() {
        $img = (intval($this->is_recommend) == Options::RECOMMEND_YES)
            ? 'yes.gif' : 'no.gif';
        return CHtml::image(Yii::app()->baseUrl . '/assets/backend/images/' . $img);
    }

    // change recommend status ajax link
    public function getIsRecommendAjaxLink() {
        return CHtml::ajaxLink($this->isRecommendIconFormat,
            Yii::app()->createUrl('backend/posts/changeRecommend'),
            array(
                'type' => 'POST',
                'data' => 'id=' . $this->id,
                'dataType' => 'text',
                'update' => "#recommend{$this->id}",
            ),
            array('id' => "recommend{$this->id}")
        );
    }

    // “是否精品”图标格式
    public function getIsPickingIconFormat() {
        $img = (intval($this->is_picking) == Options::PICKING_YES)
            ? 'yes.gif' : 'no.gif';
        return CHtml::image(Yii::app()->baseUrl . "/assets/backend/images/{$img}");
    }

    // change picking status ajax link
    public function getIsPickingAjaxLink() {
        return CHtml::ajaxLink($this->isPickingIconFormat,
            Yii::app()->createUrl('/backend/posts/changePicking'),
            array(
                'type' => 'POST',
                'data' => 'id=' . $this->id,
                'dataType' => 'text',
                'update' => "#picking{$this->id}",
            ),
            array('id' => "picking{$this->id}")
        );
    }

    // "updated" field formatted
    public function getUpdatedFormatted() {
        return ($this->updated) ? date('Y-m-d', $this->updated) : '';
    }

    // 图片地址
    public function getPicturePath() {
        return ($this->is_picture_post == self::PICTURE_POST_YES)
            ? Yii::app()->basePath . '/../upload/posts/' . $this->picture_saved_path
            : '';
    }

    // 图片来源
    public function getPictureSource() {
        return ($this->is_picture_post == self::PICTURE_POST_YES)
            ? Yii::app()->baseUrl . '/upload/posts/' . $this->picture_saved_path
            : '';
    }

    /**
     * @return string the URL that shows the detail of the post
     */
    public function getUrl() {
        return Yii::app()->createUrl('posts/view', array(
            'id' => $this->id,
            'title' => $this->title,
        ));
    }

    // 获取格式化（添加字体颜色和样式）之后的“案例名称”
    public function getTitleHtmlFormat() {
        $style = '';
        if (trim($this->title_color) != '') $style = "color: {$this->title_color};";
        if (trim($this->title_style) != '') $style .= "font-weight: {$this->title_style};";

        return ($style == '')
            ? $this->title
            : "<font style=\"{$style}\">{$this->title}</font>";
    }

    /**
     * @return array a list of links that point to the post list filtered by every tag of this post
     */
    public function getTagLinks() {
        $links = array();
        foreach(Tag::string2array($this->tags) as $tag)
            $links[] = CHtml::link(CHtml::encode($tag), array('posts/index', 'tag' => $tag));
        return $links;
    }

    /**
     * Normalizes the user-entered tags.
     */
    public function normalizeTags($attribute, $params) {
        $this->tags = Tag::array2string(array_unique(Tag::string2array($this->tags)));
    }

    /**
     * Adds a new comment to this post.
     * This method will set status and post_id of the comment accordingly.
     * @param Comment the comment to be added
     * @return boolean whether the comment is saved successfully
     */
    public function addComment($comment) {
        if (Yii::app()->params['postCommentNeedApproval']) {
            $comment->status = PostComment::STATUS_PENDING;
        } else {
            $comment->status = PostComment::STATUS_APPROVED;
        }
        $comment->post_id = $this->id;
        return $comment->save();
    }

    protected function beforeValidate() {
        if ($this->published_at) {
            $this->published_at = strtotime($this->published_at);
        }
        $this->user_id = Yii::app()->user->id;

        if ($this->is_picture_post == self::PICTURE_POST_YES) {
            if ($this->isNewRecord) {
                $this->setScenario('is_picture_post');
            } else {
                if ($this->_original_picture_path == '') {
                    $this->setScenario('is_picture_post');
                }
            }
        }

        return true;
    }

    private $_original_picture_path;
    protected function afterFind() {
        parent::afterFind();
        $this->_original_picture_path = $this->picture_saved_path;

        $this->published_at = date('Y-m-d', $this->published_at);
        $this->_oldTags = $this->tags;
    }

    protected function beforeSave() {
        parent::beforeSave();
        if (parent::beforeSave()) {
            if ($this->isNewRecord) {
                $this->user_id = Yii::app()->user->id;
            }
        }
        // 类型为“图片链接”的才做上传处理
        if ($this->is_picture_post == self::PICTURE_POST_YES) {
            $uploading_file = CUploadedFile::getInstance($this, 'picture_saved_path');
            if (is_object($uploading_file) && get_class($uploading_file) === 'CUploadedFile') {
                if (!$this->isNewRecord) {
                    @unlink(Post::model()->findByPk($this->id)->picturePath);
                }
                $filename = md5(time() . $this->title) . '.' . $uploading_file->getExtensionName();
                $this->picture_saved_path = $filename;
                $uploading_file->saveAs(Yii::app()->basePath . '/../upload/posts/' . $filename);
            } else {
                $this->picture_saved_path = $this->_original_picture_path;
            }
        } else {
            $this->picture_saved_path = '';
            @unlink(Post::model()->findByPk($this->id)->picturePath);
        }

        return true;
    }

    /**
     * This is invoked after the record is saved.
     */
    protected function afterSave() {
        parent::afterSave();
        Tag::model()->updateFrequency($this->_oldTags, $this->tags, Tag::TYPE_POST);
    }

    /**
     * This is invoked after the record is deleted.
     */
    protected function afterDelete() {
        parent::afterDelete();
        PostComment::model()->deleteAll("post_id = {$this->id}");
        Tag::model()->updateFrequency($this->tags, '', Tag::TYPE_POST);
        if ($this->is_picture_post == self::PICTURE_POST_YES) {
            @unlink($this->picturePath);
        }
    }

    public function behaviors() {
        return array(
            'CTimestampBehavior' => array(
                'class' => 'zii.behaviors.CTimestampBehavior',
                'createAttribute' => 'created',
                'updateAttribute' => 'updated',
            )
        );
    }

    protected function findBase($type = 'recent', $node = null, $limit = 12) {
        $criteria = new CDbCriteria();
        $criteria->condition = 'status = ' . Options::STATUS_PUBLISHED;
        if ($node !== null) {
            if (is_array($node)) {
                $criteria->addInCondition('node_id', $node);
            } else if (is_int($node)) {
                $criteria->addCondition("node_id = {$node}");
            }
        }
        switch (trim($type)) {
            case 'recent':
                $criteria->order = 'created DESC';
                break;
            case 'hot':
                $criteria->order = 'clicks_count DESC';
                break;
            case 'recommend':
                $criteria->addCondition('is_recommend = ' . Options::RECOMMEND_YES);
                break;
            case 'picking':
                $criteria->addCondition('is_picking = ' . Options::PICKING_YES);
                break;
            case 'picture':
                $criteria->addCondition('is_picture_post = ' . self::PICTURE_POST_YES);
                break;
            default:
                $criteria->order = 'created DESC';
                break;
        }
        $criteria->limit = $limit;

        return self::model()->findAll($criteria);
    }

    // 最新信息
    public function findRecent($node = null, $limit = 12) {
        return $this->findBase('recent', $node, $limit);
    }

    // 热门信息
    public function findHot($node = null, $limit = 12) {
        return $this->findBase('hot', $node, $limit);
    }

    //　推荐信息
    public function findRecommend($node = null, $limit = 12) {
        return $this->findBase('recommend', $node, $limit);
    }

    // 置顶信息
    public function findPicking($node = null, $limit = 12) {
        return $this->findBase('picking', $node, $limit);
    }

    // 图片信息
    public function findPicture($node = null, $limit = 12) {
        return $this->findBase('picture', $node, $limit);
    }
}